local Lang = require("common.Lang")
local Msg = require("core.Msg")
local Obj = require("core.Obj")
local ObjHuman = require("core.ObjHuman")
local Cmds = require("buffer.Cmds")
local Buffer = require("buffer.Buffer")
local sbConfig = require("excel.Shenbing").shenbing
local ObjCollect = require("core.ObjCollect")

local os = _G.os

HUMAN_STATUS_NORMAL             = 1	-- 正常状态
HUMAN_STATUS_COLLECT            = 2	-- 采集状态
HUMAN_STATUS_SIT_ONE            = 3	-- 打坐

HUMAN_STATUS_SIT_DOUBLE = 4			-- 双休
HUMAN_STATUS_FISH = 5 					-- 钓鱼
HUMAN_STATUS_MINING = 6					-- 挖矿
HUMAN_STATUS_GIDDY = 7					-- 僵直
HUMAN_STATUS_ROTATION = 8 			-- 旋风
HUMAN_STATUS_SING = 9					  -- 吟唱
HUMAN_STATUS_GUIDE = 10					-- 引导
HUMAN_STATUS_HIDE = 11					-- 隐身
HUMAN_STATUS_READY = 12					-- 回城读条
HUMAN_STATUS_TALISMAN = 13			-- 上坐骑读条
HUMAN_STATUS_ROTATION1 = 14     -- 小旋风
HUMAN_STATUS_CANGBAO = 15				-- 藏宝读条
HUMAN_STATUS_OBSERVER = 16				-- 擂台观战
HUMAN_STATUS_COPY_ENTER = 17			-- 副本进入读条
HUMAN_STATUS_WING_FLY = 18				-- 飞翔

HUMAN_STATUS_SWAP_SKILL = 20			-- 技能切换中
MAX_HUMAN_STATUS_NUM = 20				-- 最大的状态


BUFFER_SIT = 90001						-- 打坐buffer id
BUFFER_FISH = 90002						-- 钓鱼buffer id
BUFFER_MINING = 90003					-- 挖矿buffer id

-- 判断是否可以使用技能
function canSkill(obj, skillID, skillConfig)
	if obj.bufAttr.giddy and (not skillConfig or skillConfig.giddyCanSkill==0) then	   
		return 	
	end
	
	if isNoSkill(obj, skillConfig) then
		return
	end
	
	if skillID then
		if obj.obj_type == Obj.TYPE_HUMAN and not Cmds.passive.skillChange(obj, skillID) and not Cmds.passive.awake(obj) then	--技能栏切换后 只能使用变身后技能
			return 
		end
	end
	
	return true
end

function isNoSkill(obj, skillConfig)
	if obj.status == HUMAN_STATUS_OBSERVER then
		return true
	end
	if skillConfig then
		return obj.bufAttr.noSkill and skillConfig.canSkill==0
	end
end

-- 判断是否可以移动
function canMove(obj)
	if obj.status == HUMAN_STATUS_OBSERVER then
		return true
	end
	local passive = Cmds.passive
	if passive.giddy(obj) or passive.noMove(obj) then return end	--晕眩 禁止移动 禁止技能
	return true
end

-- 退出状态
function onExitStatus(human, status)
	if status == HUMAN_STATUS_NORMAL then
	
	elseif status == HUMAN_STATUS_COLLECT then
		local mm = Msg.gc.GC_DU_TIAO_CANCEL
		mm.obj_id = human.id
		Obj.sendArea(mm, human.scene_id, human.x, human.y, human.fd)
	elseif status == HUMAN_STATUS_SIT_ONE then
		Buffer.removeID(BUFFER_SIT, human)
	elseif status == HUMAN_STATUS_SIT_DOUBLE then
		Buffer.removeID(BUFFER_SIT, human)
		
	elseif status == HUMAN_STATUS_FISH then
		Buffer.removeID(BUFFER_FISH, human)
	elseif status == HUMAN_STATUS_MINING then
		Buffer.removeID(BUFFER_MINING, human)
	elseif status == HUMAN_STATUS_GIDDY then
	
	elseif status == HUMAN_STATUS_OBSERVER then
	
	elseif status == HUMAN_STATUS_ROTATION or status == HUMAN_STATUS_ROTATION1 or status == HUMAN_STATUS_SING or status == HUMAN_STATUS_GUIDE 
		or status == HUMAN_STATUS_READY  or status == HUMAN_STATUS_HIDE or status == HUMAN_STATUS_TALISMAN 
		or status == HUMAN_STATUS_CANGBAO or status == HUMAN_STATUS_COPY_ENTER  or status == HUMAN_STATUS_SWAP_SKILL then
		Buffer.delStop(human, Buffer.STOP_TYPE_STATUS)	--状态改变清理BUFF
	elseif status == HUMAN_STATUS_WING_FLY then
		
	end	
end

--　进入状态
function onEnterStatus(human, status, arg1, arg2, arg3, arg4, arg5)

	if status == HUMAN_STATUS_NORMAL then
	
	elseif status == HUMAN_STATUS_COLLECT then
		Obj.stop(human)
		Buffer.delStop(human, Buffer.STOP_TYPE_STATUS, true)	--状态改变清理BUFF
	elseif status == HUMAN_STATUS_SIT_ONE then
		Obj.stop(human)
		Buffer.add(BUFFER_SIT, human, human)
	elseif status == HUMAN_STATUS_SIT_DOUBLE then
		human.sitDoubleQinmiStartTime = os.time()
		Buffer.add(BUFFER_SIT, human, human)
	elseif status == HUMAN_STATUS_FISH then
		Buffer.add(BUFFER_FISH, human, human)
	elseif status == HUMAN_STATUS_MINING then
		Buffer.add(BUFFER_MINING, human, human)
	elseif status == HUMAN_STATUS_GIDDY then
	

	elseif status == HUMAN_STATUS_OBSERVER then
		
	elseif status == HUMAN_STATUS_ROTATION or status == HUMAN_STATUS_ROTATION1 or status == HUMAN_STATUS_SING or status == HUMAN_STATUS_GUIDE  
		or status == HUMAN_STATUS_READY  or status == HUMAN_STATUS_HIDE or status == HUMAN_STATUS_TALISMAN 
		or status == HUMAN_STATUS_CANGBAO or status == HUMAN_STATUS_COPY_ENTER  or status == HUMAN_STATUS_SWAP_SKILL then
		local buffID = arg1
		local send = arg2
		local skillLevel = arg3
		local tx = arg4
		local ty = arg5
		Buffer.add(buffID, human, send, skillLevel, tx, ty)
		if status == HUMAN_STATUS_GUIDE then
		    Obj.stop(human)
		end
	elseif status == HUMAN_STATUS_WING_FLY then
		
	end
	
end


-- 角色控制状态改变逻辑
function doHumanControlStatusChange(human, newStatus, tip, arg1, arg2, arg3, arg4, arg5)	
	local preStatus = human.status
	if preStatus == newStatus or preStatus == HUMAN_STATUS_GIDDY then -- 新旧状态相同 or 处于僵直 不处理
		return
	end

	onExitStatus(human, preStatus)
	human.status = newStatus	-- 顺序 没有特色需求不要调整	
	onEnterStatus(human, newStatus, arg1, arg2, arg3, arg4, arg5)
	if human.obj_type == Obj.TYPE_HUMAN then
	  human.db.status = human.status
		sendControlStatus(human, tip)
		if preStatus==HUMAN_STATUS_WING_FLY  then
			ObjHuman.doCalc(human)
		end
	end
		
	--if human.bufChange ~=human.bufChangeSend then	-- BUF 改变
	--	Buffer.onChange(human)
	--else
		sendViewStatus(human, true)
	--end
end

function makeViewInfo(viewInfo, sex, body, weapon, weaponEffect, pifeng,horse, bone, weapon2, weapon2Effect,bodyEffect,horseEffect, bodyColor, baowuSource, baowuEffect, head, official, leftarm, rightarm)
	viewInfo.sex  = sex or 0
	viewInfo.body = body or 0
	viewInfo.bodyEffect = bodyEffect or 0
	viewInfo.bone = bone or 0
	viewInfo.weapon = weapon or 0
	viewInfo.weaponEffect = weaponEffect or 0
	viewInfo.weapon2 = weapon2 or 0
	viewInfo.weapon2Effect = weapon2Effect or 0
	viewInfo.pifeng = pifeng or 0
	viewInfo.horse = horse or 0
	viewInfo.horseEffect = horseEffect or 0
	viewInfo.bodyColor = bodyColor or 0
  viewInfo.baowuSource = baowuSource or 0
  viewInfo.baowuEffect = baowuEffect or 0
  viewInfo.head = head or 0
  viewInfo.official = official or 0
  viewInfo.leftarm = leftarm or 0
  viewInfo.rightarm = rightarm or 0
end

-- 发送对象可视状态
function sendViewStatus(obj, areaSend, noSend)
	obj.oldDisplays = obj.oldDisplays or {}
	local old = obj.oldDisplays
	local msgRet = Msg.gc.GC_VIEW_STATUS_CHANGE
	msgRet.status = Cmds.passive.giddy(obj)==1 and HUMAN_STATUS_GIDDY or obj.status or 0	-- 特殊处理
	msgRet.objID = obj.id
	local sex = 0
	if obj.obj_type == Obj.TYPE_HUMAN then
	   msgRet.awakeColor = sbConfig[obj.db.putonShenbing] and sbConfig[obj.db.putonShenbing].awakeColor or 0
	   sex = obj.db.sex
  else
     msgRet.awakeColor = 0
	end
	makeViewInfo(msgRet.viewInfo,sex, Obj.getBodyInfo(obj))
	
	local isChange
	for k, v in pairs(msgRet) do
		if type(v) == "number" then
			if old[k] ~= v then
				old[k] = v
				isChange = true
			end
		else
			for k1, v1 in pairs(v) do 
				if old[k1] ~= v1 then
					old[k1] = v1
					isChange = true
				end
			end
		end
	end
	if noSend then return end
	if not isChange and areaSend == true then return end
	

	if obj.hide or not areaSend then
		Msg.send(msgRet, obj.fd)		
	else
		Obj.sendArea(msgRet, obj.scene_id, obj.x, obj.y)
	end
end

-- 发送角色控制状态
function sendControlStatus(human, msg)
	local msgRet = Msg.gc.GC_CONTROL_STATUS_CHANGE
	msgRet.msg = msg or ""
	msgRet.noMove = (canMove(human) == true and 0) or 1
	msgRet.noSkill = isNoSkill(human)  and 1 or 0
	msgRet.isGiddy = Cmds.passive.giddy(human) and 1 or 0
	msgRet.isLuama = Cmds.passive.luoma(human) and 1 or 0
	Msg.send(msgRet, human.fd)
end

-- 走动
function onMove(obj)
	Buffer.onMove(obj)
	if obj.obj_type ==  Obj.TYPE_HUMAN then
		if obj.status == HUMAN_STATUS_COLLECT then
			-- 如果采集 移动的话要被打断
			doHumanControlStatusChange(obj, HUMAN_STATUS_NORMAL, Lang.STRING_COLLECT_INTERUPT_MOVE)
		elseif obj.status ~= HUMAN_STATUS_ROTATION and obj.status ~= HUMAN_STATUS_ROTATION1  and obj.status ~= HUMAN_STATUS_HIDE and obj.status ~= HUMAN_STATUS_TALISMAN 
		      and obj.status ~= HUMAN_STATUS_GUIDE then	
			-- 除旋风或隐身或引导之外 走路时 都恢复默认
			doHumanControlStatusChange(obj, HUMAN_STATUS_NORMAL)
		end
	end
end

-- 跳转
function onJump(obj)
	if obj.obj_type ==  Obj.TYPE_HUMAN then
		-- 跳跃时 打断法宝读条
		if obj.status == HUMAN_STATUS_TALISMAN or obj.status == HUMAN_STATUS_ROTATION or obj.status == HUMAN_STATUS_ROTATION1 or obj.status == HUMAN_STATUS_GUIDE then
			doHumanControlStatusChange(obj, HUMAN_STATUS_NORMAL)
		end
	end
end

--攻击
function onSkill(obj)
	Buffer.onSkill(obj)
	if obj.obj_type ==  Obj.TYPE_HUMAN then
		if obj.status == HUMAN_STATUS_COLLECT then
			-- 如果采集 使用技能的话要被打断
			doHumanControlStatusChange(obj, HUMAN_STATUS_NORMAL, Lang.STRING_COLLECT_INTERUPT_ATK)
		elseif obj.status ~= HUMAN_STATUS_ROTATION and obj.status ~= HUMAN_STATUS_ROTATION1 and obj.status ~= HUMAN_STATUS_HIDE and obj.status ~= HUMAN_STATUS_GUIDE then	
			-- 除旋风或隐身或引导之外 走路时 都恢复默认
			doHumanControlStatusChange(obj, HUMAN_STATUS_NORMAL)
		end
	end
end

--击中目标
function onHit(obj, target)
    Buffer.onHit(obj, target)
end

--被攻击
function onBeHit(attacker, obj)
	Buffer.onBeHit(attacker, obj)
	if obj.obj_type ==  Obj.TYPE_HUMAN then
		if obj.status == HUMAN_STATUS_COLLECT then
			-- 如果采集 被打的话要被打断
			local collect = Obj.getObj(obj.collectObjId, obj.collectObjUid)
			if collect and collect.obj_type ==  Obj.TYPE_COLLECT then
                local config = ObjCollect.getConfig(collect)
                if config.canBreak == 1 then
                    doHumanControlStatusChange(obj, HUMAN_STATUS_NORMAL, Lang.STRING_COLLECT_INTERUPT_BE_ATK)
                end
			end
		elseif obj.status ~= HUMAN_STATUS_ROTATION and obj.status ~= HUMAN_STATUS_ROTATION1 and obj.status ~= HUMAN_STATUS_HIDE and obj.status ~= HUMAN_STATUS_GUIDE  and obj.status ~= HUMAN_STATUS_TALISMAN then	
			-- 除旋风或隐身或引导之外 走路时 都恢复默认
			doHumanControlStatusChange(obj, HUMAN_STATUS_NORMAL)
		end
	end	
end
